<?php
declare (strict_types = 1);

namespace app\middleware;

use think\facade\Db;
class Check
{
    private $default_method         = 'json';
    protected $request;
    protected   $_method            =   '';
    protected   $_timestamp         =   '';
    protected   $_noncestr          =   '';
    protected $appkey               = 'newaction';
    private  $appid                 = '';
    private  $app_secret            = '';
    private static $c_table        = 'Client';
    /**
     * 处理请求
     * 校验token
     *
     * @param \think\Request $request
     * @param \Closure       $next
     * @return Response
     */
    public function handle($request, \Closure $next)
    {
        return $next($request);
        $this->request = $request;
        $request->debug = $request->param('debug');
        if($request->debug == 2 || $request->debug == 1){
            return $next($request);
        }
        $headers = \Tools::get_all_header();
        if(isset($headers['appid']) && empty($headers['appid']) === FALSE) {
            $this->appid = $headers['appid'];
        }else{
            return \Tools::returnMsg(false,array(
                'message'   => 'appid不正确',
                'code'      => '10005'
            ),$this->default_method);
        }
        if(isset($headers['method']) && empty($headers['method']) === FALSE) {
            $this->_method = $headers['method'];
        }else{
            $this->_method = 'POST';
        }
        if(isset($headers['timestamp']) && empty($headers['timestamp']) === FALSE) {
            $this->_timestamp = $headers['timestamp'];
        }else{
            return \Tools::returnMsg(false,array(
                'message'   => '必要参数丢失',
                'code'      => '10011'
            ),$this->default_method);
        }
        if(isset($headers['noncestr']) && empty($headers['noncestr']) === FALSE) {
            $this->_noncestr = $headers['noncestr'];
        }else{
            return \Tools::returnMsg(false,array(
                'message'   => '必要参数丢失',
                'code'      => '10011'
            ),$this->default_method);
        }
        $client_info = Db::name(self::$c_table)->where(array(
            'appid' =>$this->appid
        ))->column('app_secret');
        if(empty($client_info)){
            return \Tools::returnMsg(false,array(
                'message'   => 'appid不正确',
                'code'      => '10005'
            ),$this->default_method);
        }
        $this->app_secret = $client_info[0];

        switch (strtoupper($this->_method)){
            case 'POST':
                $this->check_sign($this->request->post());
                break;
            case 'GET':
                $this->check_sign($this->request->get());
                break;
            case 'PUT':
                $this->check_sign($this->request->put());
                break;
            case 'DELETE':
                $this->check_sign($this->request->delete());
                break;
        }
        $tokeninfo = [];
        if(isset($headers['accesstoken']) && empty($headers['accesstoken']) === FALSE) {
            $tokeninfo = \Tools::checkJWTToken($headers['accesstoken']);
        }
        $request->tokeninfo = $tokeninfo;
        return $next($request);
    }
    /**
     * 校验签名
     * @param string $sign
     * @param array $data
     * @return bool
     */
    private function check_sign($data = []) {
       $sign = $this->request->get('sign');
       if(isset($data['sign'])) unset($data['sign']);
       if(empty($data) === FALSE){
           foreach ($data as $k=>$v){
               if(empty($v) && $v != 0){
                   unset($data[$k]);
               }
           }
       }
        $app_data = array(
            "appid"     => $this->appid,
            "appsecret" => $this->app_secret,
            "noncestr"  => $this->_noncestr,
            "timestamp" => $this->_timestamp,
            "method"    => $this->_method
        );
        $data = array_merge($app_data,$data);
        $res_sign = \Tools::MakeSign($data,$this->appkey);
        if($res_sign === $sign) {
            return true;
        }
        return \Tools::returnMsg(false, array(
                'message' => '签名错误1',
                'code' => '10006'
            ), $this->default_method);
    }
}
